﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;

using DotSpatial.Controls;

namespace HAGISV2
{
    /// <summary>
    /// 刘写。对图例进行拖拽的类
    /// </summary>
    public class LegendMF : HMapFunction
    {

        public LegendMF(DotSpatial.Controls.Map map)
            : base(map)
        { 
        }

        //public string IsolineLayerID;

        public IsolineLayer layer;
        
        private bool _dragging = false;
        private Point _dragPoint;  //移动时用的点
        private Point _mousePosition;

        private Point _stretchPoint; //拉伸时用的点坐标
        private LegendStretchType _stretcType = LegendStretchType.Left;  //拉伸类型
        private bool _stretching = false;


        private int _tolerancePixel = 2;

        private double Width()
        {
            double strWidth = double.MinValue;
            
            foreach (GisContour.ContourLine line in this.layer.ContourLineList)
            {
                string str = "";
                if (this.layer.IsLegendTextFormat == true)
                {
                    str = line.ContourLineValue.ToString("E" + this.layer.LegendFormatNum.ToString());
                }
                else
                {
                    str = line.ContourLineValue.ToString("F" + this.layer.LegendFormatNum.ToString());
                }

                strWidth = Math.Max(strWidth, (this.Map as DotSpatial.Controls.Map).CreateGraphics().MeasureString(str, this.layer.LegendFont).Width);
            }
           

            return this.layer.LegendWidth + strWidth;
        }

        private double Height()
        {
            return this.layer.LegendHeight;
        }

        private RectangleF LegendRect()
        {
            return new RectangleF((float)this.layer.LegendOffsetX, (float)this.layer.LegendOffsetY, 
                (float)this.Width(), this.layer.LegendHeight*this.Map.Height);
        }


        protected override void OnActivate()
        {
            base.OnActivate();
            this.Map.Invalidate();
        }

        protected override void OnDeactivate()
        {
            base.OnDeactivate();
            this.Map.Invalidate();
        }

        protected override void OnDraw(MapDrawArgs e)
        {
            if (this.layer == null) return;
            if (this.layer.Visible == false) return;
            if (this.layer.ContourLineList == null || this.layer.ContourLineList.Count == 0) return;
            if (this.layer.HyGrid == null) return;
            if (this.layer.IsShowLegend == false) return;

            this.HighLightRect(e);

            if (this._dragging)
            {
                this.DrawDragRect(e);
            }

            if (this._stretching)
            {
                this.DrawStretchRect(e);
            }


            base.OnDraw(e);
        }

        protected override void OnMouseDown(GeoMouseArgs e)
        {
            base.OnMouseDown(e);

            //进行操做前，先判断这个等值线图层是否存在图例并且图例是显示的！
            //怎么判断呢，这个还得问一下

            if (this.layer == null) return;
            if (this.layer.Visible == false) return;
            if (this.layer.ContourLineList == null || this.layer.ContourLineList.Count == 0) return;
            if (this.layer.HyGrid == null) return;
            if (this.layer.IsShowLegend == false) return;

            //设置拉伸类型
            this.SetStretchType();

            if (this._stretching == true) return;

            if (this.LegendRect().Contains(e.X, e.Y) == true)
            {
                this._dragging = true;
                this._dragPoint = e.Location;
                return;
            }                    
            
        }


        protected override void OnMouseMove(GeoMouseArgs e)
        {
            base.OnMouseMove(e);

            if (this.layer == null) return;
            if (this.layer.Visible == false) return;
            if (this.layer.ContourLineList == null || this.layer.ContourLineList.Count == 0) return;
            if (this.layer.HyGrid == null) return;
            if (this.layer.IsShowLegend == false) return;

            this._mousePosition = e.Location;

            //拖拽
            if (this._dragging == true)
            {
                //this.layer.LegendOffsetX += this._mousePosition.X - this._dragPoint.X;
                //this.layer.LegendOffsetY += this._mousePosition.Y - this._dragPoint.Y;
                RectangleF rect = this.LegendRect();
                rect = new RectangleF(rect.X + this._mousePosition.X - this._dragPoint.X, rect.Y + this._mousePosition.Y - this._dragPoint.Y, rect.Width, rect.Height);
                rect.Inflate(20, 20);
                this.Map.Invalidate(Rectangle.Ceiling(rect));
                return;
            }

            //拉伸
            if (this._stretching == true)
            {
                //this.ChangeLegendRect();
                //this.Map.Invalidate(Rectangle.Ceiling(this.LegendRect()));
               
                this.Map.Invalidate();
                return;
            }
                      
            //当鼠标移动到图例边框时，设置拉伸鼠标样式
            this.SetStretchCursor();

        }


        protected override void OnMouseUp(GeoMouseArgs e)
        {
            if (this.layer == null) return;
            if (this.layer.Visible == false) return;
            if (this.layer.ContourLineList == null || this.layer.ContourLineList.Count == 0) return;
            if (this.layer.HyGrid == null) return;
            if (this.layer.IsShowLegend == false) return;

            base.OnMouseUp(e);

            if (this._dragging == true)
            {
                this.layer.LegendOffsetX += this._mousePosition.X - this._dragPoint.X;
                this.layer.LegendOffsetY += this._mousePosition.Y - this._dragPoint.Y;
                this._dragging = false;
                this.Map.Invalidate();
            }

            if (this._stretching == true)
            {
                this.ChangeLegendRect();
                this.Map.Cursor = System.Windows.Forms.Cursors.Default;
                this._stretching = false;
                this.Map.Invalidate();
            }
        }


        private void HighLightRect(MapDrawArgs e)
        {
            e.Graphics.DrawRectangle(new Pen(System.Drawing.Color.Red, 2.0f),Rectangle.Ceiling( this.LegendRect()));
        }


        private void SetStretchCursor()
        {
            //拉伸

            //左上
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y) < this._tolerancePixel && Math.Abs(this._mousePosition.X - this.LegendRect().X) < this._tolerancePixel)
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
                //this._stretcType = LegendStretchType.LeftUp;
                return;
            }
            //右上
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y) < this._tolerancePixel && Math.Abs(this._mousePosition.X - this.LegendRect().X - this.LegendRect().Width) < this._tolerancePixel)
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeNESW;
                //this._stretcType = LegendStretchType.RightUp;
                return;
            }
            //左下
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y - this.LegendRect().Height) < this._tolerancePixel && Math.Abs(this._mousePosition.X - this.LegendRect().X) < this._tolerancePixel)
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeNESW;
                //this._stretcType = LegendStretchType.LeftBottom;
                return;
            }
            //右下
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y - this.LegendRect().Height) < this._tolerancePixel && Math.Abs(this._mousePosition.X - this.LegendRect().X - this.LegendRect().Width) < this._tolerancePixel)
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeNWSE;
                //this._stretcType = LegendStretchType.RightBottom;
                return;
            }

            //左侧
            if (Math.Abs ( this._mousePosition.X - this.LegendRect().X) <this._tolerancePixel && this._mousePosition.Y < this.LegendRect().Height + this.LegendRect().Y && this._mousePosition.Y > this.LegendRect().Y)
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeWE;
                //this._stretcType = LegendStretchType.Left;
                return;
            }
            //右侧
            if (Math.Abs(this._mousePosition.X - this.LegendRect().X - this.LegendRect().Width) < this._tolerancePixel && this._mousePosition.Y < this.LegendRect().Height + this.LegendRect().Y && this._mousePosition.Y > this.LegendRect().Y)
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeWE;
                //this._stretcType = LegendStretchType.Right;
                return;
            }
            //上侧
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y) < this._tolerancePixel && this._mousePosition.X < this.LegendRect().Width + this.LegendRect().X && this._mousePosition.X > this.LegendRect().X)
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeNS;
                //this._stretcType = LegendStretchType.Up;
                return;
            }
            //下侧
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y - this.LegendRect().Height) < this._tolerancePixel && this._mousePosition.X < this.LegendRect().Width + this.LegendRect().X && this._mousePosition.X > this.LegendRect().X)
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeNS;
                //this._stretcType = LegendStretchType.Bottom;
                return;
            }

            if (this.LegendRect().Contains(this._mousePosition))
            {
                this.Map.Cursor = System.Windows.Forms.Cursors.SizeAll;
                return;
            }

            this.Map.Cursor = System.Windows.Forms.Cursors.Default;
        }


        private void SetStretchType()
        {
            //拉伸
            this._stretchPoint = new Point(this._mousePosition.X, this._mousePosition.Y);

            //左上
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y) < this._tolerancePixel && Math.Abs(this._mousePosition.X - this.LegendRect().X) < this._tolerancePixel)
            {
                this._stretching = true;
                this._stretcType = LegendStretchType.LeftUp;
                return;
            }
            //右上
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y) < this._tolerancePixel && Math.Abs(this._mousePosition.X - this.LegendRect().X - this.LegendRect().Width) < this._tolerancePixel)
            {
                this._stretching = true;
                this._stretcType = LegendStretchType.RightUp;
                return;
            }
            //左下
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y - this.LegendRect().Height) < this._tolerancePixel && Math.Abs(this._mousePosition.X - this.LegendRect().X) < this._tolerancePixel)
            {
                this._stretching = true;
                this._stretcType = LegendStretchType.LeftBottom;
                return;
            }
            //右下
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y - this.LegendRect().Height) < this._tolerancePixel && Math.Abs(this._mousePosition.X - this.LegendRect().X - this.LegendRect().Width) < this._tolerancePixel)
            {
                this._stretching = true;
                this._stretcType = LegendStretchType.RightBottom;
                return;
            }

            //左侧
            if (Math.Abs(this._mousePosition.X - this.LegendRect().X) < this._tolerancePixel && this._mousePosition.Y < this.LegendRect().Height + this.LegendRect().Y && this._mousePosition.Y > this.LegendRect().Y)
            {               
                this._stretching = true;
                this._stretcType = LegendStretchType.Left;
                return;
            }
            //右侧
            if (Math.Abs(this._mousePosition.X - this.LegendRect().X - this.LegendRect().Width) < this._tolerancePixel && this._mousePosition.Y < this.LegendRect().Height + this.LegendRect().Y && this._mousePosition.Y > this.LegendRect().Y)
            {
                this._stretching = true;
                this._stretcType = LegendStretchType.Right;
                return;
            }
            //上侧
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y) < this._tolerancePixel && this._mousePosition.X < this.LegendRect().Width + this.LegendRect().X && this._mousePosition.X > this.LegendRect().X)
            {
                this._stretching = true;
                this._stretcType = LegendStretchType.Up;
                return;
            }
            //下侧
            if (Math.Abs(this._mousePosition.Y - this.LegendRect().Y - this.LegendRect().Height) < this._tolerancePixel && this._mousePosition.X < this.LegendRect().Width + this.LegendRect().X && this._mousePosition.X > this.LegendRect().X)
            {
                this._stretching = true;
                this._stretcType = LegendStretchType.Bottom;
                return;
            }

        }


        private void ChangeLegendRect()
        {
            if (this._stretching == false) return;

            double height;
            double width;

            switch (this._stretcType)
            {
                case LegendStretchType.Bottom:
                    height = this.Map.Height * this.layer.LegendHeight;
                    height = height + this._mousePosition.Y - this._stretchPoint.Y;
                    this.layer.LegendHeight = (float)(height / this.Map.Height);
                    break;
                case LegendStretchType.Left:
                    
                    this.layer.LegendOffsetX = this._mousePosition.X ; // this.layer.LegendOffsetX + this._mousePosition.X - this._stretchPoint.X;

                    this.layer.LegendWidth = this.layer.LegendWidth - this._mousePosition.X + this._stretchPoint.X;                   
                       
                    break;
                case LegendStretchType.LeftBottom:
                    this.layer.LegendOffsetX =  this._mousePosition.X ;
                    this.layer.LegendWidth = this.layer.LegendWidth - this._mousePosition.X + this._stretchPoint.X;                   
                    height = this.Map.Height * this.layer.LegendHeight;
                    height = height + this._mousePosition.Y - this._stretchPoint.Y;
                    this.layer.LegendHeight = (float)(height / this.Map.Height);
                    break;
                case LegendStretchType.LeftUp:
                    this.layer.LegendOffsetX =  this._mousePosition.X;
                    this.layer.LegendWidth = this.layer.LegendWidth - this._mousePosition.X + this._stretchPoint.X;                 

                     this.layer.LegendOffsetY =  this._mousePosition.Y;
                     height = this.Map.Height * this.layer.LegendHeight;
                    height = height - this._mousePosition.Y + this._stretchPoint.Y;
                    this.layer.LegendHeight = (float)height / this.Map.Height;
                    break;
                case LegendStretchType.Right:
                    width = this.layer.LegendWidth;
                    width = width + this._mousePosition.X - this._stretchPoint.X;
                    this.layer.LegendWidth = (float)width;

                    break;
                case LegendStretchType.RightBottom:
                    width = this.layer.LegendWidth;
                    width = width + this._mousePosition.X - this._stretchPoint.X;
                    this.layer.LegendWidth = (float)width;
                     height = this.Map.Height * this.layer.LegendHeight;
                    height = height + this._mousePosition.Y - this._stretchPoint.Y;
                    this.layer.LegendHeight = (float)(height / this.Map.Height);
                    break;
                case LegendStretchType.RightUp:
                    width = this.layer.LegendWidth;
                    width = width + this._mousePosition.X - this._stretchPoint.X;
                    this.layer.LegendWidth = (float)width;

                    this.layer.LegendOffsetY =  this._mousePosition.Y;
                     height = this.Map.Height * this.layer.LegendHeight;
                    height = height - this._mousePosition.Y + this._stretchPoint.Y;
                    this.layer.LegendHeight = (float)height / this.Map.Height;

                    break;
                case LegendStretchType.Up:
                    this.layer.LegendOffsetY =  this._mousePosition.Y;
                     height = this.Map.Height * this.layer.LegendHeight;
                    height = height - this._mousePosition.Y + this._stretchPoint.Y;
                    this.layer.LegendHeight = (float)height / this.Map.Height;
                    break;

            }
 
        }


        private void DrawDragRect(MapDrawArgs e)
        {
            RectangleF rect = this.LegendRect();
            e.Graphics.DrawRectangle(Pens.Red, rect.X + this._mousePosition.X - this._dragPoint.X, rect.Y + this._mousePosition.Y - this._dragPoint.Y, rect.Width, rect.Height);
        }

        private void DrawStretchRect(MapDrawArgs e)
        {
            RectangleF rect = this.LegendRect();

            switch (this._stretcType)
            {
                case LegendStretchType.Bottom :
                                      
                    e.Graphics.DrawRectangle(Pens.Red, rect.X, rect.Y, rect.Width, rect.Height + this._mousePosition.Y - this._stretchPoint.Y);

                    break;
                case LegendStretchType.Left:
                    e.Graphics.DrawRectangle(Pens.Red, this._mousePosition.X, rect.Y, rect.Width - this._mousePosition.X + this._stretchPoint.X, rect.Height);
                    break;
                case LegendStretchType.LeftBottom:
                    e.Graphics.DrawRectangle(Pens.Red, this._mousePosition.X, rect.Y, rect.Width - this._mousePosition.X + this._stretchPoint.X, rect.Height + this._mousePosition.Y - this._stretchPoint.Y);
                    break;
                case LegendStretchType.LeftUp:
                    e.Graphics.DrawRectangle(Pens.Red, this._mousePosition.X, this._mousePosition.Y, rect.Width - this._mousePosition.X + this._stretchPoint.X, rect.Height - this._mousePosition.Y + this._stretchPoint.Y);
                    break;
                case LegendStretchType.Right:
                    e.Graphics.DrawRectangle(Pens.Red, rect.X, rect.Y, rect.Width + this._mousePosition.X - this._stretchPoint.X, rect.Height);
                    break;
                case LegendStretchType.RightBottom:
                    e.Graphics.DrawRectangle(Pens.Red, rect.X, rect.Y, rect.Width + this._mousePosition.X - this._stretchPoint.X, rect.Height + this._mousePosition.Y - this._stretchPoint.Y);
                    break;
                case LegendStretchType.RightUp:
                    e.Graphics.DrawRectangle(Pens.Red, rect.X, this._mousePosition.Y, rect.Width + this._mousePosition.X - this._stretchPoint.X, rect.Height - this._mousePosition.Y + this._stretchPoint.Y);
                    break;
                case LegendStretchType.Up:
                    e.Graphics.DrawRectangle(Pens.Red, rect.X, this._mousePosition.Y, rect.Width, rect.Height - this._mousePosition.Y + this._stretchPoint.Y);
                    break;
            }
        }

    }
}
